/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.butler.cezary.syncTool.scanning.detectors;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import pl.butler.cezary.syncTool.scanning.ChangeStatus;
import pl.butler.cezary.syncTool.storage.metadata.FileVersionMetadata;
import pl.butler.cezary.syncTool.scanning.FileSensedEvent;
import pl.butler.cezary.syncTool.scanning.IFileSensedListener;
import pl.butler.cezary.syncTool.storage.Storage;

/**
 * klasa powinna zajmować się sprawdzaniem zmian w a nie zarządzaniem nimi
 * @author czarek
 */
public class ChangeDetector implements IFileSensedListener {

    //private Map<String, FileMetadata> metadanePlikow = new HashMap<String, FileMetadata>();
    private static final Logger log = Logger.getLogger("ChangeDetector");
    final TimeBasedDetector timeDetector = new TimeBasedDetector();
    final SizeBasedDetector sizeDetector = new SizeBasedDetector();
    final ChecksumBasedDetector checksumDetector = new ChecksumBasedDetector();
    private final Storage storage;
    private static final int STORE_INTERVAL=100;

    private void registerChange(final File plik, ChangeStatus typZmiany) {
        storage.storeChange(plik, typZmiany);        
        storage.suggestSave();
    }

    public ChangeDetector(Storage storage) {
        this.storage = storage;        
    }

    public void onFileSenced(FileSensedEvent eventData) {
        final File file = eventData.getPlik();
        final FileVersionMetadata metadata = storage.getCurrentFileVersionMetadata(file);
        ChangeStatus status = ChangeStatus.NEW;
        if (metadata == null) {
            registerChange(file, ChangeStatus.NEW);
            newFile(file);
            return;
        }
        status = timeDetector.checkIfChanged(file, metadata);
        if (status != ChangeStatus.NONE) {
            final ChangeStatus prevStatus = status;
            status = status.interpretWith(sizeDetector.checkIfChanged(file, metadata));

            if (status == ChangeStatus.NONE) {
                status = prevStatus.interpretWith(checksumDetector.checkIfChanged(file, metadata));
            }
        }
        switch (status) {
            case LOCAL:
                fileModified(file);
                registerChange(file, status);
                break;
            case REMOTE:
                fileModifiedRemotely(file);
        }
    }

    private void newFile(final File plik) {
        if(log.isLoggable(Level.INFO))
            log.info(String.format("Nowy plik:\t'%s'", plik.getPath()));
    }

    private void fileModified(final File plik) {
        if(log.isLoggable(Level.INFO))
            log.info(String.format("Plik '%s' został zmodyfikowany lokalnie", plik.getPath()));
    }

    private void fileModifiedRemotely(final File plik) {
        if(log.isLoggable(Level.INFO))
            log.info(String.format("Plik '%s' został zmodyfikowany na innym komputerze", plik.getPath()));
    }
    
}
